home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
emulator
/
uae-0.000
/
uae-0
/
uae-0.6.0
/
gfxlib.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-05-23
|
9KB
|
311 lines
/*
* UAE - The Un*x Amiga Emulator
*
* Graphics.library replacement
*
* (c) 1996 by Christian Schmitt <schmittc@uni-freiburg.de>
*
* (c) 1996 by Markus Gietzen
*
*/
#include "sysconfig.h"
#include "sysdeps.h"
#include <assert.h>
#include "config.h"
#include "options.h"
#include "events.h"
#include "memory.h"
#include "custom.h"
#include "newcpu.h"
#include "xwin.h"
#include "autoconf.h"
#include "filesys.h"
#include "gfxlib.h"
/* Global variables etc. */
static ULONG gfxlibname;
static CPTR Move,WritePixel,ReadPixel,SetRast,BltClear;
static ULONG gfxl_WritePixel(void)
{
CPTR rastport=regs.a[1],layer=longget(rastport);
CPTR bitmap=longget(rastport+4),adr=0L;
UWORD x=regs.d[0],minx,miny,maxx,maxy;
UWORD y=regs.d[1];
UBYTE new=0,old=0,pen=byteget(rastport+25),
depth=byteget(bitmap+5),pixel;
UWORD bpr=wordget(bitmap);
UWORD rows=wordget(bitmap+2);
CPTR Planeptr=longget(bitmap+8),Plane=0;
int i;
if(layer!=0){
rastport=longget(layer+12);
pen=byteget(rastport+25);
bitmap=longget(rastport+4);
depth=byteget(bitmap+5);
minx=wordget(layer+16);
miny=wordget(layer+18);
maxx=wordget(layer+20);
maxy=wordget(layer+22);
bpr=wordget(bitmap);
rows=wordget(bitmap+2);
} else {
minx=miny=0;
maxx=bpr*8;
maxy=rows;
}
y=y+miny;
x=x+minx;
if((x>maxx)||(y>maxy)){
regs.d[0]=-1;
return 0;
} else {
for(i=0;i<depth;i++){
Plane=longget(bitmap+8+4*i);
old=byteget(Plane+y*bpr+x/8);
if(!(pen&(1<<i))) new=old | (128>>(x%8));
else new=old&(0xff-(128>>(x%8)));
byteput(Plane+y*bpr+x/8,new);
}
}
regs.d[0]=0;
return 0;
}
static ULONG gfxl_ReadPixel(void)
{
CPTR rastport=regs.a[1];
CPTR bitmap=longget(rastport+4);
UWORD x=regs.d[0],y=regs.d[1],old;
UBYTE pen=0,depth=byteget(bitmap+5);
UWORD bpr=wordget(bitmap);
UWORD rows=wordget(bitmap+2);
CPTR PlanePtr=longget(bitmap+8),Plane=0;
int i;
for(i=0;i<depth;i++){
Plane=longget(bitmap+8+4*i);
old=byteget(Plane+y*bpr+x/8);
if(((128>>(x%8))&old)) pen=pen+(1<<i);
}
regs.d[0]=pen;
return 0;
}
static ULONG gfxl_SetRast(void) /* This function isn't working right now */
{
CPTR rastport=regs.a[1],bitmap,PlanePtr,Plane,layer;
UBYTE pen=regs.d[0],depth,mode=byteget(rastport+28);
UWORD bpr,rows,minx=0,miny=0,maxx,maxy,dx,x,y,dy;
ULONG pattern,bits=0,new,old;
int i,j;
layer=longget(rastport);
bitmap=longget(rastport+4);
PlanePtr=longget(bitmap+8);
bpr=wordget(bitmap);
rows=wordget(bitmap+2);
depth=byteget(bitmap+5);
switch(mode) { /* What else do I have to do here ? */
case 0 : break;
case 1 : pen=byteget(rastport+26);break;
default: break;
}
if(layer!=0) {
rastport=longget(layer+12);
minx=wordget(layer+16);
miny=wordget(layer+18);
maxx=wordget(layer+20);
maxy=wordget(layer+22);
} else {
maxx=bpr*8;
maxy=rows-1;
}
for(i=0;i<depth-1;i++){
Plane=longget(bitmap+8+i*4);
if((pen&(1<<i))) pattern=0xffffffff; else pattern=0;
for(y=miny;y<=maxy;y++){
x=0;dx=0,dy=0;
new=old=longget(Plane+y*bpr+minx);
while(((minx+x)%8!=0)&&(x<=maxx)){
if(pattern==0xffffffff) new=new|(1<<(minx+x)%8);
else new=new&(0xff-(1<<(minx+x)%8));
x++;
}
if(x!=0) dx=1;
byteput(Plane+y*bpr+minx,new);dy=x;
while(8+dy<=maxx){
byteput(Plane+y*bpr+minx+dx,pattern);
dx++;
dy+=8;
}
x=0;
new=byteget(Plane+y*bpr+minx+dx);
while(((minx+dy+x)%8!=0)&&(x+dy<=maxx)){
if(pattern==0xffffffff) new=new|(1<<(minx+dy+x)%8);
else new=new&(0xff-(1<<(minx+dy+x)%8));
x++;
}
byteput(Plane+y*bpr+minx+dx,new);
}
}
return 0;
}
static ULONG gfxl_BltClear(void)
{
CPTR mem=regs.a[1];
ULONG count=regs.d[0];
ULONG flags=regs.d[1];
UWORD rows,bpr;
UWORD pattern=((flags&0xffff0000)>>16);
unsigned int i;
if((flags&2)){
bpr= (count&0x0000ffff);
rows=(count>>16);
count=bpr*rows;
}
if(flags&3){
for(i=0;i<count;i+=2) wordput(mem+i,pattern);
if(count%2) byteput(mem+(count/2)*2,pattern);
}else {
for(i=0;i<count;i+=4) longput(mem+i,0);
mem=mem+(count/4)*4;
switch(count%4) {
case 0 : break;
case 1 : byteput(mem,0);break;
case 2 : wordput(mem,0);break;
case 3 : wordput(mem,0);byteput(mem+2,0);break;
default: break; /* Ooops */
}
}
return 0;
}
static ULONG gfxl_Move(void)
{
CPTR rastport=regs.a[1];
WORD x=regs.d[0];
WORD y=regs.d[1];
/* Set new coordinate */
wordput(rastport+36,x);
wordput(rastport+38,y);
/* Set Linepatcnt */
byteput(rastport+30,0x0f);
return(0);
}
/*
* Initialisation (called by AMIGA-OS !)
*/
static ULONG gfxlib_init(void)
{
CPTR gfxbase;
CPTR sysbase=regs.a[6];
int i=0;
/* Install new routines */
/* We have to call SetFunction here instead of writing direktly into the GfxBase,
because of the library checksum ! */
regs.d[0]=0;
regs.a[1]=gfxlibname;
gfxbase=CallLib(sysbase, -408); /* OpenLibrary */
regs.a[1]=gfxbase;
regs.a[0]=-240;
regs.d[0]=Move;
CallLib(sysbase, -420); /* SetFunction */
regs.a[1]=gfxbase;
regs.a[0]=-324;
regs.d[0]=WritePixel;
CallLib(sysbase, -420);
regs.a[1]=gfxbase;
regs.a[0]=-300;
regs.d[0]=BltClear;
CallLib(sysbase, -420);
regs.a[1]=gfxbase;
regs.a[0]=-234;
regs.d[0]=SetRast;
CallLib(sysbase, -420);
regs.a[0]=-318;
regs.d[0]=ReadPixel;
CallLib(sysbase,-420);
return 0;
}
/*
* Install the gfx-library-replacement
*/
void gfxlib_install(void)
{
ULONG begin, end, resname, resid;
int i;
if(!use_gfxlib) return;
fprintf(stderr, "Warning: you enabled the graphics.library replacement with -g\n"
"This may be buggy right now, and will not speed things up much.\n");
resname = ds("UAEgfxlib.resource");
resid = ds("UAE gfxlib 0.1");
gfxlibname = ds("graphics.library");
begin = here();
dw(0x4AFC); /* RTC_MATCHWORD */
dl(begin); /* our start address */
dl(0); /* Continue scan here */
dw(0x0101); /* RTF_COLDSTART; Version 1 */
dw(0x0805); /* NT_RESOURCE; pri 5 */
dl(resname); /* name */
dl(resid); /* ID */
dl(here() + 4); /* Init area: directly after this */
calltrap(deftrap(gfxlib_init)); dw(RTS);
/* start of code */
Move=here();
calltrap(deftrap(gfxl_Move));
dw(RTS);
WritePixel=here();
calltrap(deftrap(gfxl_WritePixel));
dw(RTS);
ReadPixel=here();
calltrap(deftrap(gfxl_ReadPixel));
dw(RTS);
SetRast=here();
calltrap(deftrap(gfxl_SetRast));
dw(RTS);
BltClear=here();
calltrap(deftrap(gfxl_BltClear));
dw(RTS);
end = here();
org(begin + 6);
dl(end);
org(end);
}